import * as Rx from 'rxjs'
const fs = require('fs')
const path = require('path')
const restDir = path.resolve(__dirname, "./rest")
const md5 = require('md5')
//multer
const multer = require('multer')

interface ApiService {
    path: string
    isUpload: boolean
}
interface UploadFile {
    destination: string
    encoding: string
    fieldname: string
    filename: string
    mimetype: string
    originalname: string
    path: string
    size: number
}

const getExtName = (fileName: string): string => {
    let extName
    if (fileName) {
        let dotIndex = fileName.lastIndexOf('.')
        extName = fileName.substring(dotIndex)
    }
    return extName || ''
}

const getSaveName = (file: UploadFile): string => {
    return Date.now() + '_' + md5(file.fieldname).substring(0, 6) + getExtName(file.originalname)
}
/**
 * 设置上传文件的api service
 * @param app 
 * @param api 
 */
const setupUpload = (app: any, api: ApiService) => {
    let storage = multer.diskStorage({
        destination: function (req: any, file: UploadFile, cb: Function) {
            cb(null, app.get('public') + '/uploads')
        },
        filename: function (req: any, file: UploadFile, cb: Function) {
            cb(null, getSaveName(file))
        }
    })
    const upload = multer({ storage })
    app.use(api.path,
        upload.array('cover_image'),
        function (req: any, res: any, next: Function) {
            req.feathers.files = req.files
            next()
        },
        api,
    )
    app.service(api.path).before({
        create: [
            function (hook: any) {
                let files: UploadFile[] = hook.params.files
                if (files) {
                    files.forEach(item => {
                        hook.data[item.fieldname] = getSaveName(item)
                    })
                }
            }
        ]
    })
}

/**
 * 设置api service
 * @param app 
 * @param api 
 */
const setup = (app: any, api: ApiService) => {
    app.use(`${api.path}`, api)
}

export = function () {
    let app = this
    let files = fs.readdirSync(restDir)
    let apis: ApiService[] = files.map((item: string) => {
        let last = item.lastIndexOf(".js")
        let name = item.substring(0, last)
        let clazz = require(`./rest/${name}`)
        return new clazz()
    })

    Rx.Observable.from(apis)
        .subscribe((api: ApiService) => {
            if (api.isUpload) {
                setupUpload(app, api)
            } else {
                setup(app, api)
            }
        })
}